package com.blueocean_health.care.management.common.base.time;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

import com.blueocean_health.care.management.common.base.em.TimeType;

public class TimeUtils {
	
	private static final ZoneId SYSTEM_ZONE_ID = ZoneId.systemDefault();
	private static final String P_DAY = "yyyy-MM-dd";
	private static final String P_SECOND = P_DAY + " HH:mm:ss";
	
	public static DateFormat dateFormat(String pattern) {
		return new SimpleDateFormat(pattern);
	}
	
	/**
	 * 日期格式化：MM月dd日 hh:mm
	 * 
	 * @param date
	 * @return
	 */
	public static String date2Str(Date date) {
		if (date == null) {
			return "";
		}
		return dateFormat(P_DAY).format(date);
	}
	

	
	public static Date str2Date(String datestr) {
		try {
			return dateFormat(P_SECOND).parse(datestr);
		} catch (ParseException e) {
			return null;
		}
	}
	
	/**
	 * 获取默认格式的当前时间 yyyy-MM-dd HH:mm:ss
	 */
	public static String getTime(){
		return getTime(TimeType.yyyy_MM_dd_HH_mm_ss);
	}

	/**
	 * 获取默认格式的当前时间戳 yyyy-MM-dd HH:mm:ss.SSS
	 */
	public static String getTimesTamp(){
		return getTime(TimeType.yyyy_MM_dd_HH_mm_ss_SSS);
	}

	/**
	 *	根据对应枚举类型的格式获取时间
	 */
	public static String getTime(TimeType timeType){
		if(timeType.type() == 1) {
			return LocalDateTime.now().format(patternFormat(timeType));
		}
		else if(timeType.type() == 2) {
			return LocalDate.now().format(patternFormat(timeType));
		}
		else {
			return LocalTime.now().format(patternFormat(timeType));
		}
			
	}
	
	
	public static Date subtractDay(Date d, int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) - day);
		return cal.getTime();
	}
	
	
	public static Date subtractHour(Date d, int hour) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) - hour);
		return cal.getTime();
	}
	
	/**
	 * 给指定日期添加天数，并返回
	 *@author lcf
	 *@date 2018年6月22日
	 *@version 1.0
	 */
	public static Date addDay(Date d, int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) + day);
		return cal.getTime();
	}

	
	/**
	 * @param date
	 *            日期
	 * @param otherDate
	 *            另一个日期
	 * @return 相差天数
	 */
	public static long getIntervalDays(Date date, Date otherDate) {
		long time = otherDate.getTime() - date.getTime();
		return (long) time / (24 * 60 * 60 * 1000);
	}
	
	/**
	 * 把字符串类型的时间格式化为Date类型
	 */
	public static Date getDateByString(String time, TimeType timeType){
		if(timeType.type() == 1) {
			return Date.from(LocalDateTime.parse(time, patternFormat(timeType)).atZone(SYSTEM_ZONE_ID).toInstant());
		}
		else if(timeType.type() == 2) {
			return Date.from(LocalDate.parse(time, patternFormat(timeType)).atStartOfDay().atZone(SYSTEM_ZONE_ID).toInstant());
		}
		else {
			return Date.from(LocalTime.parse(time, patternFormat(timeType)).atDate(LocalDate.now()).atZone(SYSTEM_ZONE_ID).toInstant());
		}
	}
	
	/**
	 * 把Date类型的时间格式化为String类型
	 */
	public static String getStringByDate(Date time, TimeType timeType){
		LocalDateTime localDateTime = LocalDateTime.ofInstant(time.toInstant(), SYSTEM_ZONE_ID);
		if(timeType.type() == 1) {
			return localDateTime.format(patternFormat(timeType));
		}
		else if(timeType.type() == 2) {
			return localDateTime.toLocalDate().format(patternFormat(timeType));
		}
		else {
			return localDateTime.toLocalTime().format(patternFormat(timeType));
		}
	}
	
	/**
	 * 比较两个时间的大小 
	 * <pre>
	 * 	start <  end   ==> true
	 * 	end   >  start ==> false
	 * </pre>
	 * @param start	开始时间
	 * @param end	结束时间
	 */
	public static boolean compare(String start, String end, TimeType type){
		return compare(getDateByString(start, type), getDateByString(end, type));
	}
	
	/**
	 * 比较两个时间的大小 
	 * <pre>
	 * 	start <  end   ==> true
	 * 	end   >  start ==> false
	 * </pre>
	 * @param start	开始时间
	 * @param end	结束时间
	 */
	public static boolean compare(Date start, Date end){
		return end.getTime() >= start.getTime();
	}


	/**
	 * 比较某个时间是否在时间段内
	 * @param start	开始时间
	 * @param end	结束时间
	 * @param param	判断的时间
	 */
	public static boolean compare(Date param,Date start, Date end){
		if (end.getTime() > param.getTime() && param.getTime() > start.getTime()){
			return true;
		} else if (end.getTime() >= param.getTime() && param.getTime() > start.getTime()) {
			return true;
		} /*
		每单的结束时间和其他单的开始时间重叠
		else if (end.getTime() > param.getTime() && param.getTime() >= start.getTime()) {
			return true;
		}*/ else if (start.getTime() == end.getTime() && param.getTime() == start.getTime()) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * 与系统当前时间进行比较
	 * <pre>
	 * 	time  <  now  ==> true
	 * 	now   >  time ==> false
	 * </pre>
	 * @param time
	 * @return
	 */
	public static boolean compare(Date time){
		return System.currentTimeMillis() >= time.getTime();
	}
	
	/**
	 * 与系统当前时间进行比较
	 * <pre>
	 * 	time  <  now  ==> true
	 * 	now   >  time ==> false
	 * </pre>
	 * @param time
	 * @return
	 */
	public static boolean compare(String time, TimeType type){
		return System.currentTimeMillis() >= getDateByString(time, type).getTime();
	}
	
	/**
	 * 验证传入的日期是否符合指定格式 并验证是否合法
	 * @param time
	 * @param type
	 * @return
	 */
	public static boolean validate(String time, TimeType type){
		try {
			//TODO 试试能不能用JDK8模式改进一下~
			SimpleDateFormat dateFormat = new SimpleDateFormat(type.value());
			dateFormat.setLenient(false);
			dateFormat.parse(time);
			return true;
		} catch (ParseException e) {
			return false;
		}
	}
	
	//转化时间类型
	private static DateTimeFormatter patternFormat(TimeType type){
		return DateTimeFormatter.ofPattern(type.value());
	}
	
	// 获得年份
	public static int getYear(Date d){
		Calendar cal = Calendar.getInstance();
		cal.setTime(d);
		return cal.get(Calendar.YEAR);
	}
	
	/**
	 * 校验日期格式 yyyy.MM.dd
	 * @param date
	 * @return true:格式异常 false:格式正常
	 */
	public static boolean checkDate(String date) {
		try {
			DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
			// 用来控制是否将正确格式的不正确时间转化成正确的时间，默认为true，设置为false时，如果时间不正确，不会自动转化，，而是抛出java.text.ParseException异常。
			dateFormat.setLenient(false);
			dateFormat.parse(date);
		} catch (ParseException e) {
			return true;
		}
		return false;
	}
	
	/**
	 * 计算两个时间的时间差
	 * 
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static String dateDiff(Date startTime, Date endTime) {
		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
		long nh = 1000 * 60 * 60;// 一小时的毫秒数
		long nm = 1000 * 60;// 一分钟的毫秒数
		long ns = 1000;// 一秒的毫秒数

		long diff = endTime.getTime() - startTime.getTime();
		long day = diff / nd;// 计算差多少天
		long hour = diff % nd / nh;// 计算差多少小时
		long min = diff % nd % nh / nm;// 计算差多少分钟
		long sec = diff % nd % nh % nm / ns;// 计算差多少秒//输出结果
		String daystr = day < 10 ? "0" + day : "" + day;
		String hourstr = hour < 10 ? "0" + hour : "" + hour;
		String minstr = min < 10 ? "0" + min : "" + min;
		String secstr = sec < 10 ? "0" + sec : "" + sec;
		return daystr + "/" + hourstr;
		//return daystr + "天" + hourstr + "小时" + minstr + "分钟" + secstr + "秒";
	}


	public static String getDatePoor(Date endDate, Date nowDate) {

		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		long diff = endDate.getTime() - nowDate.getTime();
		// 计算差多少天
		long day = diff / nd;
		// 计算差多少小时
		long hour = diff % nd / nh;
		// 计算差多少分钟
		long min = diff % nd % nh / nm;

		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return day + "天" + hour + "小时" + min + "分钟";
	}

}
